﻿#ifndef SyncFixedQueue_h__2013_10_16__15_25
#define SyncFixedQueue_h__2013_10_16__15_25

#include "Lock.h"
#include "atom.h"

namespace df
{
	//线程安全
	//半锁(write lock,read lock-free)循环队列
	//Size必须为2的n次方
	template<typename T, uint32_t Size>
	class SyncFixedQueue
	{
	private:
		uint32_t head_;
		volatile uint32_t tail_;
		T buffer_[Size];

		df::Lock writeLock_;

	public:

		df::Lock & GetLock()
		{
			return writeLock_;
		}

		SyncFixedQueue()
			: head_(0)
			, tail_(0)
		{
		
			static_assert(std::is_pod<T>::value, "need for speed");
			
			static_assert(Size % 2==0, "Size must equal 2^n ");
		}

		uint32_t GetSize() const
		{
			return tail_ % Size - head_ % Size;
		}

		bool Add(T val)
		{
			DF_LOCKED(writeLock_);

			//队列满
			if ((tail_ + 1) % Size == head_ % Size)
				return false;

			buffer_[tail_ % Size] = val;

			tail_++;

			return true;
		}

		bool Pop(T & out)
		{
			uint32_t index;
			do
			{
				index = head_;
				//队列空
				if (index == tail_)
					return false;

				out = buffer_[index % Size];

			} while (df::AtomCompareExchange(&head_, index, index + 1) != index);

			return true;
		}

		DF_DISABLE_COPY_ASSIGN(SyncFixedQueue);
	};

}


#endif // SyncFixedQueue_h__2013_10_16__15_25
